package com.xiangyang.service.impl;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.xiangyang.config.OSSConfig;
import com.xiangyang.entity.FileEntity;
import com.xiangyang.entity.LoginUser;
import com.xiangyang.entity.User;
import com.xiangyang.entity.dto.Result;
import com.xiangyang.mapper.FileMapper;
import com.xiangyang.mapper.IUserMapper;
import com.xiangyang.service.IFileUploadService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@Service
public class FileUploadServiceImpl implements IFileUploadService {

    @Value("${upload.path}")
    private String uploadPath;
    @Autowired
    private IUserMapper userMapper;
    @Autowired
    private FileMapper fileMapper;
    @Autowired
    private OSSConfig ossProperties;

    @Override
    public Result uploadFile(MultipartFile file) {
        if (file.isEmpty()) {
            return Result.ok("文件不能为空");
        }
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        // 计算文件的哈希值
        String fileHash = getFileHash(file);
        // 检查文件是否已经存在
        QueryWrapper<FileEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("file_hash", fileHash);
        FileEntity existingFile = fileMapper.selectOne(queryWrapper);
        if (existingFile != null) {
            Map<String, Object> map = new HashMap<>();
            map.put("meg", "头像没有发生变化");
            map.put("filePath", existingFile.getFilePath());
            return Result.ok(map);
        }
        // 生成唯一的文件名
        String originalFilename = file.getOriginalFilename();
        String fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));
        String uniqueFileName = UUID.randomUUID().toString() + fileExtension;
        // 构建用户目录
        String userDirectory = uploadPath + loginUser.getUserDetailInfo().getUserName();
        File filePath = new File(userDirectory);
        if (!filePath.exists()) {
            filePath.mkdir();
        }
        // 创建目标文件路径
        Path targetLocation = Paths.get(userDirectory, uniqueFileName);
        // 保存文件
        try {
            Files.copy(file.getInputStream(), targetLocation);
            // 更新用户头像路径
            UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("user_phone", loginUser.getUsername())
                    .set("user_avatar", targetLocation.toString());
            userMapper.update(updateWrapper);
            // 记录文件信息
            FileEntity fileEntity = new FileEntity();
            fileEntity.setUserId(loginUser.getUserDetailInfo().getUserId());
            fileEntity.setFileName(uniqueFileName);
            fileEntity.setFilePath(targetLocation.toString());
            fileEntity.setFileHash(fileHash);
            fileEntity.setUploadTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            fileMapper.insert(fileEntity);
        } catch (IOException e) {
            return Result.error(500, e.getMessage());
        }
        return Result.ok(targetLocation.toString());
    }

    private String getFileHash(MultipartFile file) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] bytes = file.getBytes();
            byte[] digest = md.digest(bytes);
            StringBuilder sb = new StringBuilder();
            for (byte b : digest) {
                sb.append(String.format("%02x", b));
            }
            return sb.toString();
        } catch (NoSuchAlgorithmException | IOException e) {
            throw new RuntimeException(e.getMessage());
        }
    }

    @Override
    public Result avatarFile(MultipartFile file) throws IOException {
        //获取文件的输入流
        InputStream inputStream = file.getInputStream();
        //获取文件名
        String filename = file.getOriginalFilename();
        //获取文件后缀名
        System.out.println();
        //避免文件覆盖
        //断言语句，文件名不为null
        assert filename != null;
        String newFileName = UUID.randomUUID() + filename.substring(filename.lastIndexOf("."));
        // 上传文件到OSS
        OSS ossClient = new OSSClientBuilder().build(ossProperties.getEndpoint(), ossProperties.getAccessKeyId(), ossProperties.getAccessKeySecret());
        ossClient.putObject(ossProperties.getBucketName(), newFileName, inputStream);

        System.out.println(ossProperties.getEndpoint());
        // 拼接完整的文件URL
        String fileUrl = ossProperties.getEndpoint().split("//")[0] + "//" + ossProperties.getBucketName() + "." + ossProperties.getEndpoint().split("//")[1] + "/" + newFileName;

        // 关闭OSS客户端
        ossClient.shutdown();
        // 更新用户头像路径
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("user_phone", loginUser.getUsername())
                .set("user_avatar", fileUrl);
        userMapper.update(updateWrapper);

        return Result.ok(fileUrl);
    }
}